package com.cn.stepLock.chain;

import com.cn.stepLock.enums.ExecuteStatus;
import com.cn.stepLock.event.StartProcessTaskEvent;
import com.cn.stepLock.exception.MessageException;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.LockSupport;

import static com.cn.stepLock.chain.ChainUtils.startThread;

/**
 * @author Aaron
 * @desc
 * @createTime 2022-02-24 3:04
 * @since
 */
public class HeadChain extends ConstentChain implements Runnable {


    private ChainHelper chainHelper;

    private Thread executeThread;

    public HeadChain(ChainHelper chainHelper) {
        this.chainHelper = chainHelper;
    }

    @Override
    public void run() {

        List<Task> tasks = new ArrayList<>();
        while (true){
            try {
                Thread.sleep(50L);
            } catch (InterruptedException e) {
                break;
            }
            /**
             * 上一次没有执行完毕，等待执行完毕
             */
            if (!tasks.isEmpty() && tasks.stream().filter(x->x.finaleFinished || x.throwable!=null).count()<tasks.size()){
                continue;
            }
            tasks = new ArrayList<>();
            Task task;
            while ((task=linkedBlockingQueue.poll())!=null){
                tasks.add(task);
            }
            if (!tasks.isEmpty()){
                chainHelper.setChainExceptTaskCount(tasks.size());
                tasks.forEach(x->LockSupport.unpark(x.ownerThread));
            }
        }
    }

    void start(){
        this.executeThread = startThread(this);
    }

    @Override
    void stop() {
        this.executeThread.interrupt();
    }

    @Override
    public void executeTask(Task task) {
        offer(task);
        LockSupport.park();
        ChainEventApplication.pulishEvent(new StartProcessTaskEvent(task));
    }

}
